package com.xt.base.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;

public class CopyUtils {

	/**
	 * 拷贝�?��同名同类型的属�?�?
	 * 
	 * @param desc
	 * @param org
	 */
	public static void copyAllProperties(Object desc, Object org) {
		try {
			BeanUtils.copyProperties(desc, org);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 当orig的属性为 null 的就不拷贝到 dest
	 * 
	 * @param dest
	 * @param orig
	 */
	@SuppressWarnings("unchecked")
	public static void copyNotNullProperties(Object dest, Object orig) {
		// Validate existence of the specified beans
		if (dest == null) {
			throw new IllegalArgumentException("No destination bean specified");
		}
		if (orig == null) {
			throw new IllegalArgumentException("No origin bean specified");
		}

		Object origValue = null;
		String name = null;
		try {
			// Copy the properties, converting as necessary
			if (orig instanceof DynaBean) {
				DynaProperty origDescriptors[] = ((DynaBean) orig)
						.getDynaClass().getDynaProperties();
				for (int i = 0; i < origDescriptors.length; i++) {
					name = origDescriptors[i].getName();
					if (PropertyUtils.isWriteable(dest, name)) {
						origValue = ((DynaBean) orig).get(name);
						if (origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			} else if (orig instanceof Map) {
				Iterator names = ((Map) orig).keySet().iterator();
				while (names.hasNext()) {
					name = (String) names.next();
					if (PropertyUtils.isWriteable(dest, name)) {
						origValue = ((Map) orig).get(name);
						if (origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			} else /* if (orig is a standard JavaBean) */{
				PropertyDescriptor origDescriptors[] = PropertyUtils
						.getPropertyDescriptors(orig);
				for (int i = 0; i < origDescriptors.length; i++) {
					name = origDescriptors[i].getName();
					if ("class".equals(name)) {
						continue; // No point in trying to set an object's
									// class
					}
					if (PropertyUtils.isReadable(orig, name)
							&& PropertyUtils.isWriteable(dest, name)) {
						origValue = PropertyUtils.getSimpleProperty(orig, name);
						if (origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 当dest的属性为 null 的就从orig中拷�?
	 * 
	 * @param dest
	 *            目标对象
	 * @param orig
	 *            源对�?
	 */
	@SuppressWarnings("unchecked")
	public static void copyForDestNullProperties(Object dest, Object orig) {
		// Validate existence of the specified beans
		if (dest == null) {
			throw new IllegalArgumentException("No destination bean specified");
		}
		if (orig == null) {
			throw new IllegalArgumentException("No origin bean specified");
		}

		Object destValue = null;
		Object origValue = null;
		String name = null;
		try {
			// Copy the properties, converting as necessary
			if (orig instanceof DynaBean) {
				DynaProperty origDescriptors[] = ((DynaBean) orig)
						.getDynaClass().getDynaProperties();
				for (int i = 0; i < origDescriptors.length; i++) {
					name = origDescriptors[i].getName();
					if (PropertyUtils.isWriteable(dest, name)) {
						origValue = getValue(orig, name);
						destValue = getValue(dest, name);
						if (destValue == null && origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			} else if (orig instanceof Map) {
				Iterator names = ((Map) orig).keySet().iterator();
				while (names.hasNext()) {
					name = (String) names.next();
					if (PropertyUtils.isWriteable(dest, name)) {
						origValue = getValue(orig, name);
						destValue = getValue(dest, name);
						if (destValue == null && origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			} else /* if (orig is a standard JavaBean) */{
				PropertyDescriptor origDescriptors[] = PropertyUtils
						.getPropertyDescriptors(orig);
				for (int i = 0; i < origDescriptors.length; i++) {
					name = origDescriptors[i].getName();
					if ("class".equals(name)) {
						continue; // No point in trying to set an object's
									// class
					}
					if (PropertyUtils.isReadable(orig, name)
							&& PropertyUtils.isWriteable(dest, name)) {
						origValue = getValue(orig, name);
						destValue = getValue(dest, name);
						if (destValue == null && origValue != null)
							BeanUtils.copyProperty(dest, name, origValue);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public static Object getValue(Object o, String name)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		Object value = null;
		if (o instanceof DynaBean) {
			value = ((DynaBean) o).get(name);
		} else if (o instanceof Map) {
			value = ((Map) o).get(name);
		} else {
			value = PropertyUtils.getSimpleProperty(o, name);
		}
		return value;
	}
}
